package com.leyou.user.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.leyou.common.auth.pojo.Payload;
import com.leyou.common.auth.pojo.UserInfo;
import com.leyou.common.auth.utils.JwtUtils;
import com.leyou.common.constants.MQConstants;
import com.leyou.common.exception.pojo.ExceptionEnum;
import com.leyou.common.exception.pojo.LyException;
import com.leyou.common.utils.BeanHelper;
import com.leyou.common.utils.CookieUtils;
import com.leyou.user.config.JwtProperties;
import com.leyou.user.mapper.UserDetailMapper;
import com.leyou.user.mapper.UserMapper;
import com.leyou.user.pojo.AddressDTO;
import com.leyou.user.pojo.User;
import com.leyou.user.pojo.UserDTO;
import com.leyou.user.pojo.UserDetail;
import org.apache.commons.lang.RandomStringUtils;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PathVariable;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 用户业务
 */
@Service
@Transactional
public class UserService {
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private UserDetailMapper userDetailMapper;
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private AmqpTemplate amqpTemplate;
    @Autowired
    private BCryptPasswordEncoder passwordEncoder;
    @Autowired
    private JwtProperties jwtProps;


    public Boolean checkData(String data, Integer type) {
        //1.封装条件
        User user = new User();
        switch (type) {
            case 1:
                user.setUsername(data);
                break;
            case 2:
                user.setPhone(data);
                break;
            default:
                throw new LyException(ExceptionEnum.INVALID_PARAM_ERROR);
        }
        QueryWrapper<User> queryWrapper = Wrappers.query(user);

        //2.执行查询，返回结果
        return userMapper.selectCount(queryWrapper) == 0;
    }

    public void sendSmsCode(String phone) {
        //1.生成6位随机验证码
        String code = RandomStringUtils.randomNumeric(6);

        //2.把生成的验证码保存到redis中，以便后续注册时验证
        redisTemplate.opsForValue().set(phone, code, 4, TimeUnit.DAYS);

        //3.把手机号和验证码发送给MQ
        Map<String, String> msgMap = new HashMap<>();
        msgMap.put("phone", phone);
        msgMap.put("code", code);
        amqpTemplate.convertAndSend(
                MQConstants.Exchange.SMS_EXCHANGE_NAME,
                MQConstants.RoutingKey.VERIFY_CODE_KEY,
                msgMap);

    }

    public void register(User user, String code) {
        //1.取出redis的验证码
        String redisCode = redisTemplate.opsForValue().get(user.getPhone());

        //2.判断和用户输入的验证码是否一致
        if (redisCode == null || !redisCode.equals(code)) {
            throw new LyException(ExceptionEnum.INVALID_VERIFY_CODE);
        }

        try {
            //3.对密码进行加密
            String encodePwd = passwordEncoder.encode(user.getPassword());
            user.setPassword(encodePwd);

            //4.保存用户信息
            userMapper.insert(user);
        } catch (Exception e) {
            e.printStackTrace();
            throw new LyException(ExceptionEnum.INSERT_OPERATION_FAIL);
        }
    }

    public User findUserByNameAndPwd(String username, String password) {
        //1.判断用户名是否存在
        User user = new User();
        user.setUsername(username);
        QueryWrapper<User> queryWrapper = Wrappers.query(user);

        User loginUser = userMapper.selectOne(queryWrapper);

        if (loginUser == null) {
            throw new LyException(ExceptionEnum.INVALID_USERNAME_PASSWORD);
        }

        //2.判断密码是否正确
        if (!passwordEncoder.matches(password, loginUser.getPassword())) {
            throw new LyException(ExceptionEnum.INVALID_USERNAME_PASSWORD);
        }

        return loginUser;
    }

    public AddressDTO findAddressById(Long userId, Long id) {
        AddressDTO address = new AddressDTO();
        address.setId(1L);
        address.setStreet("珠吉路58号津安创业园一层黑马程序员");
        address.setCity("广州");
        address.setDistrict("天河区");
        address.setAddressee("小峰峰");
        address.setPhone("15800000000");
        address.setProvince("广东");
        address.setPostcode("510000");
        address.setIsDefault(true);
        return address;
    }


    /**
     * 获取左侧列表的用户(详情)信息
     *
     * @param request
     * @return
     */
    public UserDTO findUser(HttpServletRequest request) {
        UserInfo info = this.getUserInfo(request);

        //通过id查询userDetail信息
        UserDetail userDetail = userDetailMapper.selectById(info.getId());

        UserDTO userDTO = new UserDTO();
        if (userDetail != null) {
            //如果用户详情存在，则返回详情信息
            userDTO.setUsername(userDetail.getName());
            userDTO.setImage(userDetail.getImage());
        } else {
            userDTO.setUsername(info.getUsername());
        }

        return userDTO;

    }

    private UserInfo getUserInfo(HttpServletRequest request) {
        //获取登录后的用户信息
        Payload<UserInfo> payload = null;
        try {
            String token = CookieUtils.getCookieValue(request, jwtProps.getCookie().getCookieName());
            payload = JwtUtils.getInfoFromToken(token, jwtProps.getPublicKey(), UserInfo.class);
        } catch (Exception e) {
            e.printStackTrace();
            throw new LyException(ExceptionEnum.UNAUTHORIZED);
        }

        return payload.getInfo();
    }

    /**
     * 获取表单数据添加信息
     *
     * @param userDetail
     */
    public void saveUser(UserDetail userDetail, HttpServletRequest request) {
        //获取用户信息
        UserInfo info = this.getUserInfo(request);

        //设置id
        userDetail.setId(info.getId());

        //判断数据库有没有
        UserDetail user = userDetailMapper.selectById(info.getId());
        if (user == null) {
            //没有则插入
            userDetailMapper.insert(userDetail);
        } else {
            //有则修改
            userDetailMapper.updateById(userDetail);
        }
    }

    /**
     * 获取用户详情信息
     *
     * @return
     */
    public UserDetail findUserDetail(HttpServletRequest request) {

        UserInfo info = this.getUserInfo(request);
        UserDetail userDetail = userDetailMapper.selectById(info.getId());

        if (userDetail == null) {
            throw new LyException(500, "未找到用户详情");
        }

        return userDetail;
    }

    /**
     * 保存图片
     *
     * @param image
     */
    public void saveImg(String image, HttpServletRequest request) {

        UserInfo info = this.getUserInfo(request);

        UserDetail userDetail = userDetailMapper.selectById(info.getId());

        //判断是否有数据，没有则插入
        if (userDetail == null) {
            UserDetail detail = new UserDetail();
            detail.setId(info.getId());
            detail.setImage(image);
            userDetailMapper.insert(detail);
        } else {
            userDetail.setImage(image);
            userDetailMapper.updateById(userDetail);
        }
    }
}
